﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows.Threading;
using Microsoft.WindowsAPICodePack.Shell;
using TouchExplorer.Entities;
using TouchExplorer.FileComparers;

namespace TouchExplorer
{
    public class ExplorerViewModel : INotifyPropertyChanged, IDisposable
    {
        public enum DisplayType
        {
            List,
            Tiles
        }

        private List<TouchDirectory> _rootDirectories = new List<TouchDirectory>();

        public List<TouchDirectory> RootDirectories
        {
            get
            {
                return this._rootDirectories;
            }
            set
            {
                this._rootDirectories = value;
            }
        }

        private List<TouchFile> _rootFiles = new List<TouchFile>();

        public List<TouchFile> RootFiles
        {
            get
            {
                return this._rootFiles;
            }
            set
            {
                this._rootFiles = value;
            }
        }

        static public IKnownFolder RootFolder = KnownFolders.Computer;

        public event PropertyChangedEventHandler PropertyChanged;

        public event EventHandler CurrentPathChanged;

        public Dispatcher Dispatcher { get; set; }

        private DisplayType _display = DisplayType.List;

        public DisplayType Display
        {
            get
            {
                return this._display;
            }
            set
            {
                this._display = value;
                this.OnPropertyChanged("Display");
            }
        }

        /*public ObservableCollection<KeyValuePair<string, IComparer<TouchFile>>> FilesSorting { get; set; }*/

        private IComparer<TouchFile> _selectedSorting;

        public IComparer<TouchFile> SelectedSorting
        {
            get
            {
                return this._selectedSorting;
            }
            set
            {
                this._selectedSorting = value;
                this.OnPropertyChanged("SelectedSorting");
                var lst = Files.ToList();
                lst.Sort(value);
                Files.Clear();
                foreach (var touchFile in lst)
                {
                    Files.Add(touchFile);
                }
            }
        }

        public ObservableCollection<TouchDirectory> CurrentPath { get; set; }

        public ObservableCollection<TouchDirectory> Directories { get; set; }

        private TouchDirectory _currentDirectory;

        public TouchDirectory CurrentDirectory
        {
            get
            {
                return this._currentDirectory;
            }
            set
            {
                this._currentDirectory = value;
                this.OnPropertyChanged("CurrentDirectory");
            }
        }


        private ObservableCollection<TouchFile> _files;

        public ObservableCollection<TouchFile> Files
        {
            get
            {
                return this._files;
            }
            set
            {
                this._files = value;
                this.OnPropertyChanged("Files");
            }
        }

        private DirectoryContentLoader _loader;
        private TouchDirectory _selectedDirectory;

        public TouchDirectory SelectedDirectory
        {
            get
            {
                return this._selectedDirectory;
            }
            set
            {
                this._selectedDirectory = value;

                if (_loadingDir)
                {
                    return;
                }
                if (_loader != null)
                {
                    _loader.Abort();
                }

                _loadingDir = true;
                try
                {
                    _loader = new DirectoryContentLoader(this);
                    _loader.Execute(value);
                    CurrentDirectory = value;
                    SelectedDirectory = null;
                }
                finally
                {
                    _loadingDir = false;
                    this.OnPropertyChanged("SelectedDirectory");
                }
            }
        }

        public ExplorerViewModel(Dispatcher disp)
        {
            this.Dispatcher = disp;
            Files = new ObservableCollection<TouchFile>();
            CurrentPath = new ObservableCollection<TouchDirectory>();
            Directories = new ObservableCollection<TouchDirectory>();
            SelectedSorting = new FileSortByName();
        }

        private bool _loadingDir;


        //private Task _dirImagesLoading;        

        protected void OnPropertyChanged(string p)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(p));
        }

        public void Dispose()
        {
            if (_loader != null)
                _loader.Abort();
        }

        internal void SetSorting(string sortType, string sortDirection)
        {
            IComparer<TouchFile> res = null;
            if (sortType == "SortByName")
            {
                res = new FileSortByName();
            }
            else if (sortType == "SortBySize")
            {
                res = new FileSortByLength();
            }
            else if (sortType == "SortByDate")
            {
                res = new FileSortByDate();
            }
            else if (sortType == "SortByExtension")
            {
                res = new FileSortByExtension();
            }

            if (res != null && sortDirection == "Desc")
                res = new Inverter<TouchFile>(res);

            SelectedSorting = res;
        }

        internal void SelectFolder(string folderPath)
        {
            TouchDirectory dir = null;
            if (Directory.Exists(folderPath))
            {
                dir = new TouchDirectory(new DirectoryInfo(folderPath));
            }
            else
            {
                try
                {
                    var shell = ShellObject.FromParsingName(folderPath);
                    dir = new TouchDirectory(shell);
                }
                catch (Exception)
                {
                    
                }
            }

            if (dir != null)
            {
                SelectedDirectory = dir;
            }
        }

        public bool NeverLoaded
        {
            get
            {
                return _loader == null;
            }
        }
    }
}
